﻿namespace Atomic.Plugins.Users.Application
{
    using System;

    using Atomic.Images;
    using Atomic.Exceptions;
    using Atomic.Modules.Security;
    using Atomic.Core.Security;
    using Atomic.Plugins.Users.Domain;
    using Atomic.Plugins.Users.Data;

    /// <summary>
    /// 用户应用服务。
    /// </summary>
    public class UserAppService : IUserAppService
    {
        /// <summary>
        /// 用户数据访问器。
        /// </summary>
        private readonly IUserRepository _userRepository = null;

        /// <summary>
        /// 会员服务。
        /// </summary>
        private readonly IMembershipService _membershipService = null;

        /// <summary>
        /// 初始化用户应用服务。
        /// </summary>
        /// <param name="userRepository">用户数据访问器。</param>
        /// <param name="membershipService">会员服务。</param>
        public UserAppService(IUserRepository userRepository, IMembershipService membershipService)
        {
            this._userRepository = userRepository;
            this._membershipService = membershipService;
        }

        #region 获得用户详细信息

        /// <summary>
        /// 获得用户详细信息。
        /// </summary>
        /// <param name="userId">用户编号。</param>
        /// <returns>用户详细信息。</returns>
        public UserDescriptor GetUser(int userId)
        {
            return this._userRepository.GetUser(userId);
        }

        /// <summary>
        /// 获得用户详细信息。
        /// </summary>
        /// <param name="accountNumber">用户怅号。</param>
        /// <returns>用户详细信息。</returns>
        public UserDescriptor GetUser(string accountNumber)
        {
            return this._userRepository.GetUser(accountNumber);
        }

        #endregion

        #region 注册新用户

        /// <summary>
        /// 注册新用户。
        /// </summary>
        /// <param name="registerNewUserModel">新用户注册信息。</param>
        /// <returns>是否注册成功。</returns>
        public bool RegisterNewUser(RegisterNewUserModel registerNewUserModel)
        {
            if (registerNewUserModel == null)
            {
                throw new ArgumentNullException("registerNewUserModel", "registerNewUserModel 对象不可以是 null。");
            }

            var user = UserFactory.Create(registerNewUserModel.AccountNumber, registerNewUserModel.Password, registerNewUserModel.Name, registerNewUserModel.Email);

            return this.SaveUser(user);
        }

        /// <summary>
        /// 保存用户
        /// </summary>
        /// <param name="user">新用户信息。</param>
        private bool SaveUser(IUser user)
        {
            return this._userRepository.Create(user, this.GetDefaultRoles());
        }

        /// <summary>
        /// 获得注册默认角色的编号列表。
        /// </summary>
        /// <returns></returns>
        private string GetDefaultRoles()
        {
            return SystemRoles.Normal.ToString();
        }

        #endregion

        #region 修改密码

        /// <summary>
        /// 修改用户密码。
        /// </summary>
        /// <param name="changePasswordModel">修改密码信息。</param>
        /// <returns>修改用户密码操作状态。</returns>
        public ChangePasswordStatus ChangePassword(ChangePasswordModel changePasswordModel)
        {
            if (changePasswordModel == null || string.IsNullOrWhiteSpace(changePasswordModel.AccountNumber))
            {
                throw new ArgumentNullException("changePasswordModel 对象不可以是 null。");
            }

            var user = this._membershipService.GetUserByAccountNumber(changePasswordModel.AccountNumber);

            if (user != null)
            {
                //判断旧密码是否填写正确。
                if(!user.Account.EqualPassword(changePasswordModel.OldPassword))
                {
                    return ChangePasswordStatus.OldPasswordError;
                }

                //判断新密码与确认密码是否一致。
                if (changePasswordModel.NewPassword == changePasswordModel.ConfirmPassword)
                {
                    if (user.Account != null)
                    {
                        //修改密码。
                        user.Account.ChangePassword(changePasswordModel.NewPassword);

                        //保存修改结果。
                        this._userRepository.ChangePassword(user.Id, user.Account.Password);

                        //返回成功操作状态。
                        return ChangePasswordStatus.Success;
                    }
                }
                else
                {
                    //您输入的新密码与确认密码不一致。
                    return ChangePasswordStatus.ConfirmPasswordError;
                }
            }
            else
            {
                throw new Exception("您当前登录的用户不存在或者已经被删除。");
            }

            return ChangePasswordStatus.Error;
        }

        #endregion

        #region 修改头像

        /// <summary>
        /// 上传头像。
        /// </summary>
        /// <param name="userId">用户编号。</param>
        /// <param name="uploadImage">上传图片信息。</param>
        /// <returns></returns>
        public ViewIconImage UploadIcon(int userId, UploadImage uploadImage)
        {
            string newFileName;

            var view = ImageManager.Current.LoadImage(uploadImage, () => UserIconManager.Current.GetSaveDirectory(userId) + userId, out newFileName);

            if (view == null)
            {
                throw new AtomicException("头像上传失败。");
            }

            //保存头像后缀名。
            var result = this._userRepository.ChangeIcon(userId, view.FileExt);

            if (result)
            {
                ViewIconImage iconImage = new ViewIconImage();

                iconImage.ViewWidth = view.ViewWidth;
                iconImage.ViewHeight = view.ViewHeight;
                iconImage.Image = UserIconManager.Current.GetIcon(userId, newFileName, IconSize.Normal);
                iconImage.BigImage = UserIconManager.Current.GetIcon(userId, newFileName, IconSize.Big);
                iconImage.SmallImage = UserIconManager.Current.GetIcon(userId, newFileName, IconSize.Small);

                return iconImage;
            }

            return null;
        }

        /// <summary>
        /// 修改头像。
        /// </summary>
        /// <param name="accountNumber">用户账号。</param>
        /// <param name="cutImage">裁剪图片输入信息。</param>
        public ChangeIconStatus ChangeIcon(string accountNumber, CutImageModel cutImage)
        {
            var user = this.GetUser(accountNumber);

            if (user == null)
            {
                return ChangeIconStatus.LoginInvalid;
            }

            string sourceImagePath = string.Empty;

            if (!string.IsNullOrWhiteSpace(user.Image))
            {
                string savePath = UserIconManager.Current.GetSaveDirectory(user.Id);
                sourceImagePath = savePath + user.Id.ToString() + user.Image;
                ImageManager.Current.CutImage(sourceImagePath, savePath, (int)IconSize.Big, true, cutImage, user.Id.ToString(), (int)IconSize.Small);

                return ChangeIconStatus.Success;
            }

            return ChangeIconStatus.NotUpload;
        }

        #endregion
    }
}